package cn.icare.cms.controller.restful;

import cn.icare.cms.UserService;
import cn.icare.cms.aop.UserLog;
import cn.icare.cms.model.ro.EditUserRO;
import cn.icare.cms.model.vo.rest.RespMsgVO;
import cn.icare.cms.model.vo.rest.UserLoginRespVO;
import cn.icare.cms.model.vo.rest.UserVO;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping(value = "/rest/user")
@Api(tags = "REST员工")
public class UserController extends BaseController {
    @Resource
    private UserService userService;
    private final String FALL_STRING = "请求失败,服务繁忙!";

    /**
     * URL:http://{ip}:{port}/rest/user/login
     * method:POST
     *
     * @param name
     * @param password
     * @return
     */
    @PostMapping("/login")
    @HystrixCommand(fallbackMethod = "loginFall")
    @UserLog(desc = "用户登录")
    @ApiOperation(value = "用户登录", notes = "登录成功以后,返回token信息,密码需要进行base64编码然后再传入,禁止传入明文")
    public ResponseEntity<RespMsgVO> login(@RequestParam(name = "name") String name, @RequestParam(name = "password") String password) {
        UserLoginRespVO userLoginRespVO = this.userService.login(name, password);
        if (userLoginRespVO != null) {
            return super.getRespOk(userLoginRespVO);
        } else {
            return super.getRespFail("用户名或密码错误");
        }
    }

    /**
     * URL:http://{ip}:{port}/rest/user/logout
     * method:POST
     *
     * @param name
     * @param password
     * @return
     */
    @PostMapping("/logout")
    @HystrixCommand(fallbackMethod = "logoutFall")
    @UserLog(desc = "用户注销")
    @ApiOperation(value = "用户注销", notes = "用户注销,密码需要进行base64编码然后再传入,禁止传入明文")
    public ResponseEntity<RespMsgVO> logout(@RequestParam(name = "name") String name, @RequestParam(name = "password") String password) {
        this.userService.logout(name, password);
        return super.getRespOk();
    }

    /**
     * URL:http://{ip}:{port}/rest/user/updatepwd
     * method:POST
     *
     * @param id
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @PostMapping("/updatepwd")
    @HystrixCommand(fallbackMethod = "updatePWDFall")
    @UserLog(desc = "修改用户密码")
    @ApiOperation(value = "修改用户密码", notes = "修改用户密码,密码需要进行base64编码然后再传入,禁止传入明文")
    public ResponseEntity<RespMsgVO> updatePWD(@RequestParam(name = "id") Integer id,
                                               @RequestParam(name = "oldPassword") String oldPassword,
                                               @RequestParam(name = "newPassword") String newPassword) {
        if (this.userService.updatePassword(id, oldPassword, newPassword)) {
            return super.getRespOk(id);
        } else {
            return super.getRespFail("原密码不正确");
        }
    }

    /**
     * URL:http://{ip}:{port}/rest/user
     * method:POST
     *
     * @param userVO
     * @return
     */
    @PostMapping()
    @HystrixCommand(fallbackMethod = "createOneFall")
    @UserLog(desc = "新增单个用户")
    @ApiOperation(value = "新增单个用户", notes = "user表新增单个用户,密码需要进行base64编码然后再传入,禁止传入明文")
    public ResponseEntity<RespMsgVO> createOne(@RequestBody @Valid UserVO userVO) {
        //检查用户名是否重复
        boolean isExists= this.userService.isExists(userVO.getUsername());
        if(isExists)
        {
            return  super.getRespFail("账号已经存在，请换一个");
        }
        Long id = this.userService.createOne(userVO);
        if (id >= 0) {
            return super.getRespOk(id);
        } else {
            return super.getRespFail();
        }
    }

    /**
     * URL:http://{ip}:{port}/rest/user/{id}
     * method:DELETE
     *
     * @param id
     * @return
     */
    @DeleteMapping("/{id}")
    @HystrixCommand(fallbackMethod = "deleteOneFall")
    @UserLog(desc = "删除单个用户")
    @ApiOperation(value = "删除单个用户", notes = "user表删除符合主键的单个用户")
    public ResponseEntity<RespMsgVO> deleteOne(@PathVariable("id") Integer id) {
        if (this.userService.deleteOne(id)) {
            return super.getRespOk();
        } else {
            return super.getRespFail();
        }
    }

    /**
     * URL:http://{ip}:{port}/rest/user?ids={ids}
     * method:DELETE
     *
     * @param ids
     * @return
     */
    @DeleteMapping()
    @HystrixCommand(fallbackMethod = "deleteBatchFall")
    @UserLog(desc = "删除多个用户")
    @ApiOperation(value = "删除多个用户", notes = "user表删除符合主键的多个用户")
    public ResponseEntity<RespMsgVO> deleteBatch(@RequestParam("ids") List<Integer> ids) {
        if (this.userService.deleteBatch(ids)) {
            return super.getRespOk();
        } else {
            return super.getRespFail();
        }
    }

    /**
     * URL:http://{ip}:{port}/rest/user/{id}
     * method:GET
     *
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    @HystrixCommand(fallbackMethod = "getOneFall")
    @ApiOperation(value = "查询单个用户", notes = "user表返回符合主键的单个用户")
    public ResponseEntity<RespMsgVO> getOne(@PathVariable("id") Integer id) {
        return super.getRespOk(this.userService.getOne(id));
    }

    /**
     * URL:http://{ip}:{port}/rest/user?args={args}
     * method:GET
     *
     * @return
     */
    @GetMapping()
    @HystrixCommand(fallbackMethod = "getListFall")
    @ApiOperation(value = "查询多个用户", notes = "user表返回符合条件的多个用户")
    public ResponseEntity<RespMsgVO> getList(@RequestParam(name = "name", required = false) String name,
                                             @RequestParam(name = "pageNum", required = false, defaultValue = "${cms.defaultValue.pageNum}") Integer pageNum,
                                             @RequestParam(name = "pageSize", required = false, defaultValue = "${cms.defaultValue.pageSize}") Integer pageSize) {
        return super.getRespOk(this.userService.getList(name, pageNum, pageSize));
    }

    /**
     * URL:http://{ip}:{port}/rest/user
     * method:POST
     *
     * @param userVO
     * @return
     */
    @PutMapping()
    @UserLog(desc = "修改单个用户")
    @ApiOperation(value = "修改单个用户", notes = "user表修改单个用户,密码需要进行base64编码然后再传入,禁止传入明文")
    public ResponseEntity<RespMsgVO> updateOne(@RequestBody @Valid EditUserRO userVO) {

        Boolean result = this.userService.updateOne(userVO);
        if (result) {
            return super.getRespOk();
        } else {
            return super.getRespFail();
        }
    }


    /**
     * URL:http://{ip}:{port}/rest/user/login
     * method:POST
     *
     * @param token
     * @return
     */
    @PostMapping("/refreshToken")
    @UserLog(desc = "token过期后通过refresh自动刷新功能 ")
    @ApiOperation(value = "用户登录", notes = "登录成功以后,返回token信息,密码需要进行base64编码然后再传入,禁止传入明文")
    public ResponseEntity<RespMsgVO> refreshToken(@RequestParam(name = "token") String token) {
        UserLoginRespVO userLoginRespVO = this.userService.refreshToken(token);
        if (userLoginRespVO != null) {
            return super.getRespOk(userLoginRespVO);
        } else {
            return super.getRespUnauthorized();
        }
    }

    //region fallback methods

    private ResponseEntity<RespMsgVO> loginFall(String name, String password) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> logoutFall(String name, String password) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> updatePWDFall(Integer id, String oldPassword, String newPassword) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> createOneFall(UserVO userVO) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> deleteOneFall(Integer id) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> deleteBatchFall(List<Integer> ids) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> getOneFall(Integer id) {
        return super.getRespFail(this.FALL_STRING);
    }

    private ResponseEntity<RespMsgVO> getListFall(String name, Integer pageNum, Integer pageSize) {
        return super.getRespFail(this.FALL_STRING);
    }

    //endregion
}
